package com.moleq.device.printer;

import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Locale;

import jp.co.casio.caios.framework.device.LinePrinter;
import jp.co.casio.caios.framework.device.lineprintertools.BuildinEx840;
import jp.co.casio.caios.framework.device.lineprintertools.LinePrinterDeviceBase;

public class CasioPrinter extends Printer {

	private final static char[] ESC_BASE_CH = { 0x1B, '|' };
	private final static char[] LINEFEED_CH = { '\n' };
	private final static char ESC_CANCEL = '!';

	private final static String ESC_BASE = CharBuffer.wrap(ESC_BASE_CH).toString();
	private final static String PAPER_CUT = "P";
	private final static String PAPER_FEED_CUT = "fP";
	private final static String BITMAP = "B";
	private final static String TOP_LOGO = "tL";
	private final static String BOTTOM_LOGO = "bL";
	private final static String MULTI_LINE_FEED = "lF";
	private final static String ONE_LINE_FEED = CharBuffer.wrap(LINEFEED_CH).toString();
	private final static String BARCODE = "R";
	private final static String SINGLE_SIZE = "1C";
	private final static String DOUBLE_SIZE = "2C";
	private final static String DOUBLE_HEIGHT = "3C";
	private final static String DOUBLE_WIDTH_HEIGHT = "4C";

	private LinePrinter lp;

	private BuildinEx840 lpd;

	public CasioPrinter() {
		lineWidth = 46;
	}

	@Override
	public void print() {
		if (rows != null) {
			String printContent = "";
			for (int i = 0; i < rows.count(); i++) {
				String rowContent = "";
				PrinterBufferRow printBufferRow = rows.get(i);
				boolean noFontSize = true;
				String sizeStr = "";
				
				rowContent = printBufferRow.getContent(lineWidth);
				
				for (int j = 0; j < printBufferRow.columns.count() && noFontSize ; j++) {

					PrinterBufferColumn buffercolumn = printBufferRow.columns.get(j);
					if (noFontSize) {
						switch (buffercolumn.fontSize) {
						case FONT_SINGLE_SIZE:
							sizeStr = SINGLE_SIZE;
							noFontSize = false;
							break;
						case FONT_DOUBLE_SIZE:
							sizeStr = DOUBLE_SIZE;
							noFontSize = false;
							break;
						case FONT_DOUBLE_HEIGHT:
							sizeStr = DOUBLE_HEIGHT;
							noFontSize = false;
							break;
						}
					}
//					rowContent += buffercolumn.getContent(lineWidth);
				}
				printContent += ESC_BASE + sizeStr + rowContent ;
			}

			print(printContent);
		}

	}

	@Override
	public void print(String buffer) {
		mIsBusy = true;
		try {
			lpd.init();

			lp.printNormal(buffer);

			byte[] lfs = new byte[] { 0x1B, 'd', 5 }; // Line feed
			sendToExPrinter(lpd, lfs);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		mIsBusy = false;

	}

	@Override
	public String getPrinterName() {
		return Printer.CASIO_VX100_PRINTER;
	}

	@Override
	public void open() {
		
		try {
			
			lpd = new BuildinEx840();
			lp = new LinePrinter();

			String sCountry = Locale.getDefault().getCountry();
			if (sCountry.equals(Locale.TRADITIONAL_CHINESE.getCountry())) {
				lpd.setMulticharMode(LinePrinterDeviceBase.MULTICHARMODE_BIG5);
			}else{
				lpd.setMulticharMode(LinePrinterDeviceBase.MULTICHARMODE_JISKANJI);
			}
			lpd.initCutter();
			lp.open(lpd);
			lpd.open();
			
			mIsAvailable = true;
			mEnable = true;
		} catch (Exception e) {
			mIsAvailable = false;
			mEnable = false;
			
		}

	}

	@Override
	public void close() {
		mIsAvailable = false;
		
		if (lpd != null) {
			lpd.close(); // close device
		}
		if (lp != null) {
			lp.close(); // close line printer.
		}

	}

	@Override
	public void cutPaper() {
		byte[] lfs = new byte[] { 0x1B, 'i' }; // Paper Cut
		sendToExPrinter(lpd, lfs);

	}

	private void sendToExPrinter(BuildinEx840 dev, byte[] inStr) {

		try {
			dev.write(inStr);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
